package com.siwei.mes.service.experiment.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.siwei.mes.common.query.PageQuery;
import com.siwei.mes.entity.ShxhSynchronizedata;
import com.siwei.mes.entity.UploadLaboratoryEntity;
import com.siwei.mes.entity.erp.Itemorder;
import com.siwei.mes.entity.erp.Rwdextra;
import com.siwei.mes.entity.erp.RwdextraExtend;
import com.siwei.mes.entity.erp.RwdextraInfo;
import com.siwei.mes.entity.experiment.Experiment;
import com.siwei.mes.entity.experiment.ExperimentItemorder;
import com.siwei.mes.entity.experiment.ExperimentTask;
import com.siwei.mes.entity.vo.ExperimentVo;
import com.siwei.mes.enums.TestProjectEnum;
import com.siwei.mes.mapper.ShxhSynchronizedataMapper;
import com.siwei.mes.mapper.erp.RwdextraExtendMapper;
import com.siwei.mes.mapper.experiment.ExperimentItemorderMapper;
import com.siwei.mes.mapper.experiment.ExperimentMapper;
import com.siwei.mes.mapper.experiment.ExperimentTaskMapper;
import com.siwei.mes.mapper.order.OrderMapper;
import com.siwei.mes.service.experiment.ExperimentTaskService;
import com.siwei.mes.sync.config.SyncProcessorService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 试验台账与任务关系(ExperimentTask)表服务实现类
 *
 * @author linzi
 * @since 2023-12-18 22:11:48
 */
@Slf4j
@Service
public class ExperimentTaskServiceImpl implements ExperimentTaskService {
    @Resource
    private ExperimentTaskMapper experimentTaskMapper;
    @Resource
    private ExperimentItemorderMapper experimentItemorderMapper;
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private RwdextraExtendMapper rwdextraExtendMapper;
    @Resource
    private ExperimentMapper experimentMapper;
    @Resource
    private SyncProcessorService syncProcessorService;
    @Resource
    private ShxhSynchronizedataMapper shxhSynchronizedataMapper;


    @Override
    public void update(ExperimentTask entity) {
        ExperimentTask experimentTask = experimentTaskMapper.selectByPrimaryKey(entity.getId());
        assertTrue(experimentTask == null, "试验台账与任务关系信息不存在");
        experimentTaskMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void delete(Long id) {
        ExperimentTask experimentTask = experimentTaskMapper.selectByPrimaryKey(id);
        assertTrue(experimentTask == null, "试验台账与任务关系信息不存在");
        experimentTaskMapper.deleteByPrimaryKey(id);
    }

    @Override
    public PageInfo<ExperimentTask> getPage(PageQuery<ExperimentTask, ExperimentTask> query) {
        ExperimentTask searchParam = query.getParams();
        return PageHelper.startPage(query.getPageNum(), query.getPageSize())
                .doSelectPageInfo(() -> experimentTaskMapper.getList(searchParam));
    }

    @Override
    public ExperimentTask loadById(Long id) {
        return experimentTaskMapper.loadById(id);
    }

    @Override
    public List<ExperimentTask> getAll(ExperimentTask entity) {
        return experimentTaskMapper.getList(entity);
    }

    @Override
    public List<Rwdextra> selectByExperimentId(Long experimentId) {
        List<Rwdextra> rwdextraList = experimentTaskMapper.selectByExperimentId(experimentId);
        this.payloadOtherInfo(rwdextraList, experimentId);
        return rwdextraList;
    }

    /**
     * 组装其它信息
     *
     * @param rwdextraList 任务单信息
     * @param experimentId 试验委托id
     */
    private void payloadOtherInfo(List<Rwdextra> rwdextraList, Long experimentId) {
        if (rwdextraList.isEmpty()) {
            return;
        }
        /**key :frwdh value 对应的小票发货方量*/
        Map<Integer, Float> fhQuantityMap = new HashMap<>();//发货数量map
        Map<Integer, Float> scQuantityMap = new HashMap<>();//生产数量map
        Map<Integer, Float> behalfNumberMap = new HashMap<>();//小票代表数量map
        /**获取对应试验台账下所有的小票信息*/
        List<Itemorder> itemorderList = experimentItemorderMapper.selectByExperimentId(experimentId);
        for (Itemorder itemorder : itemorderList) {
            if (itemorder == null) {
                continue;
            }
            /**这里操作发货方量*/
            float fhQuantity = 0;
            if (fhQuantityMap.containsKey(itemorder.getFrwdh())) {
                fhQuantity = fhQuantityMap.get(itemorder.getFrwdh());
            }
            fhQuantity += itemorder.getFhquantity();
            fhQuantityMap.put(itemorder.getFrwdh(), fhQuantity);

            /**这里操作生产方量*/
            float scQuantity = 0;
            if (scQuantityMap.containsKey(itemorder.getFrwdh())) {
                scQuantity = scQuantityMap.get(itemorder.getFrwdh());
            }
            scQuantity += itemorder.getScquantity();
            scQuantityMap.put(itemorder.getFrwdh(), scQuantity);

            /**这里操作代表方量*/
            float behalfNumber = 0;
            if (behalfNumberMap.containsKey(itemorder.getFrwdh())) {
                behalfNumber = behalfNumberMap.get(itemorder.getFrwdh());
            }
            behalfNumber += itemorder.getBehalfNumber();
            behalfNumberMap.put(itemorder.getFrwdh(), behalfNumber);
        }
        /**直接遍历复制*/
        for (Rwdextra rwdextra : rwdextraList) {
            rwdextra.setIsexcep(orderMapper.queryIsexcep(rwdextra.getFrwdh()));
            if (fhQuantityMap.containsKey(rwdextra.getFrwdh())) {
                rwdextra.setFhquantity(fhQuantityMap.get(rwdextra.getFrwdh()));
            }
            if (scQuantityMap.containsKey(rwdextra.getFrwdh())) {
                rwdextra.setScquantity(scQuantityMap.get(rwdextra.getFrwdh()));
            }

            /**所有该任务单的小票代表数量累计之和*/
            if (behalfNumberMap.containsKey(rwdextra.getFrwdh())) {
                rwdextra.setCountItemorderBehalfNumber(behalfNumberMap.get(rwdextra.getFrwdh()));
            }

            RwdextraInfo rwdextraInfo = RwdextraInfo.jsonToObj(rwdextra.getExtrainfo());
            rwdextra.setRwdextraInfo(rwdextraInfo);

            String projectNameNew = rwdextra.getProjectNameNew();
            String contractNameNew = rwdextra.getContractNameNew();
            String buildNameNew = rwdextra.getBuildNameNew();

            rwdextra.setProjectNameNew(this.unescapeJava(projectNameNew));
            rwdextra.setContractNameNew(this.unescapeJava(contractNameNew));
            rwdextra.setBuildNameNew(this.unescapeJava(buildNameNew));

            RwdextraExtend rwdextraExtend = rwdextraExtendMapper.selectByFRwdh(rwdextra.getFrwdh());
            if (rwdextraExtend != null) {
                rwdextra.setRwdextraExtend(rwdextraExtend);
            }
        }
    }

    @Override
    public PageInfo<Rwdextra> selectByExperimentIdPage(PageQuery<ExperimentVo, ExperimentVo> query) {
        ExperimentVo searchParam = query.getParams();
        Long experimentId = searchParam.getExperimentId();
        PageInfo<Rwdextra> pageInfo = PageHelper.startPage(query.getPageNum(), query.getPageSize())
                .doSelectPageInfo(() -> experimentTaskMapper.selectByExperimentId(experimentId));
        this.payloadOtherInfo(pageInfo.getList(), experimentId);
        return pageInfo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByExperimentIdAndTaskId(Long experimentId, Integer taskId) {
        log.info("开始删除混凝土试验委托与任务关系，试验委托id:【{}】,任务id:【{}】", experimentId, taskId);

        Experiment experiment = experimentMapper.loadById(experimentId);
        assertTrue(experiment == null, "试验委托信息不存在");

        List<ExperimentTask> list = experimentTaskMapper.getList(new ExperimentTask().setExperimentId(experimentId).setTaskId(taskId));
        assertTrue(list.isEmpty(), "试验台账与任务关系信息不存在");

        for (ExperimentTask task : list) {
            experimentTaskMapper.deleteByPrimaryKey(task.getId());
        }

        List<Itemorder> itemorders = experimentItemorderMapper.selectByExperimentIdFrwdh(experimentId, taskId);
        for (Itemorder itemorder : itemorders) {
            log.info("开始删除小票信息，试验委托id:【{}】,小票id:【{}】", experimentId, itemorder.getItid());
            experimentItemorderMapper.delete(new ExperimentItemorder().setExperimentId(experimentId).setItemorderId(itemorder.getItid()));
        }

        /**重新计算试验委托数量*/
        List<Itemorder> itemorderList = experimentItemorderMapper.selectByExperimentId(experimentId);
        double behalfNumber = itemorderList.stream().map(Itemorder::getScquantity).reduce((float) 0, Float::sum);
        Experiment updateInfo = new Experiment();
        updateInfo.setId(experimentId);
        updateInfo.setBehalfNumber(behalfNumber);
        updateInfo.init(false);
        experimentMapper.updateByPrimaryKeySelective(updateInfo);


        /**这里判断是否已经上传到协会，如果没有上传到协会就不推送*/
        ShxhSynchronizedata shxhSynchronizedata = shxhSynchronizedataMapper.selectByExperimentIdOne(experimentId);
        if (shxhSynchronizedata != null && shxhSynchronizedata.getSampleId() != null) {
            log.info("删除混凝土试验委托和任务关系，推送到协会处理代表数量。");
            /**推送到协会*/
            List<String> experimentIdList = new ArrayList<>();
            experimentIdList.add(experimentId.toString());

            List<Experiment> hntExperiment = new ArrayList<>();


            if (experiment.getEntrustExperiment().contains(TestProjectEnum.CONCRETE_PARAM_KYQD.getName())) {
                hntExperiment = experimentMapper.getHntKyExperiment();
            } else if (experiment.getEntrustExperiment().equals(TestProjectEnum.CONCRETE_PARAM_KSDJ.getName())) {
                hntExperiment = experimentMapper.getHntKsExperiment();
            }
            syncProcessorService.submitRequest(new UploadLaboratoryEntity().setExperimentId(experimentIdList).setUploadState(0).setHntExperiment(hntExperiment));
        }
    }

    /**
     * 格式化字符串
     *
     * @param str
     * @return
     */
    public String unescapeJava(String str) {
        if (StringUtils.isNotBlank(str)) {
            return StringEscapeUtils.unescapeJava(str).replaceAll("\"", "");
        }
        return null;
    }
}
